package dao;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser;


import modelo.Livro;
import modelo.Usuario;
import modelo.Comentario;
import modeloRanking.LivroRanking;
import modeloRanking.UsuarioRanking;
import conexao.ConnectionFactory;

public class LivroDao {
	private Connection conexao;

	public LivroDao() throws ClassNotFoundException {
		this.conexao = new ConnectionFactory().getConnection();
	}

	// adicionarLiro
	public void adicionar(Livro livro, int codigo) {

		Livro livroAuxAdicionar = new Livro();
		livroAuxAdicionar = buscarLivro(livro, codigo);
		System.out.println("codigoAux" + livroAuxAdicionar.getCodigo());
		if (livroAuxAdicionar.getCodigo() == 0) {

			String sql = "insert into livro" + "(isbn, titulo, editora)"
					+ "values(?,?,?)";

			try {

				PreparedStatement stmt = conexao.prepareStatement(sql);

				stmt.setString(1, livro.getIsbn());
				stmt.setString(2, livro.getTitulo());
				stmt.setString(3, livro.getEditora());
				stmt.execute();

				stmt.close();

				leitorDoLivro(livro, codigo);

				System.out.println("gravado!");

				conexao.close();

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			// colocar um novo leitor para um livro que já existe
			adicionarLeitorAoLivro(livroAuxAdicionar, codigo);
		}
	}

	private void leitorDoLivro(Livro livro, int codigo) {

		String consulta = "select id from livro where isbn=" + "'"
				+ livro.getIsbn() + "' and  titulo=" + "'" + livro.getTitulo()
				+ "'";
		PreparedStatement pst;
		int codigoDoLivro = 0;
		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet resultSet = pst.executeQuery();

			while (resultSet.next()) {
				codigoDoLivro = resultSet.getInt("id");
			}
			resultSet.close();
			pst.close();
			livro.setCodigo(codigoDoLivro);
			adicionarLeitorAoLivro(livro, codigo);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void adicionarLeitorAoLivro(Livro livro, int codigo) {

		String sql = "insert into usuariolivro" + "(codusuario, codlivro)"
				+ "values(?,?)";

		try {

			PreparedStatement stmt = conexao.prepareStatement(sql);

			stmt.setInt(1, codigo);
			stmt.setInt(2, livro.getCodigo());
			stmt.execute();

			stmt.close();
			conexao.close();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// listar Livro do usuario;
	public List<Livro> listarLivro(int codigo) {

		String consulta = "select * from livro where id in (select codlivro from usuariolivro where "
				+ codigo + "=codusuario);";
		PreparedStatement pst;
		List<Livro> livros = new ArrayList<Livro>();

		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet result = pst.executeQuery();

			while (result.next()) {
				// cria o objeto Livro

				Livro livro = new Livro();
				livro.setIsbn(result.getString("isbn"));
				livro.setTitlo(result.getString("titulo"));
				livro.setEditora(result.getString("editora"));

				// inserindo contato na lista
				livros.add(livro);
			}
			result.close();
			pst.close();
			return livros;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return livros;
	}

	public List<LivroRanking> rankginLivro() {
		List<LivroRanking> livros = new ArrayList<LivroRanking>();
		String consulta = "select distinct codlivro, titulo, count(codlivro) as soma from (usuariolivro join livro on codlivro=id) group by codlivro, titulo order by soma DESC";
		PreparedStatement pst;
		System.out.println("entrou no rankgin livro");
		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet resultSet = pst.executeQuery();

			while (resultSet.next()) {
				System.out.println("detro do while");
				LivroRanking livro = new LivroRanking();
				livro.setCod(resultSet.getInt("codlivro"));
				livro.setTitulo(resultSet.getString("titulo"));
				livro.setQuantLivros(resultSet.getInt("soma"));
				livros.add(livro);
			}
			resultSet.close();
			pst.close();
			System.out.println("tamanho"+livros.size());
			return livros;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return livros;
	}

	
	
	
	public List<Livro> listarTodosLivros() {
		String consulta = "select distinct * from livro";
		PreparedStatement pst;
		List<Livro> todosOsLivros = new ArrayList<Livro>();

		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet result = pst.executeQuery();
			while (result.next()) {
				// cria o objeto Livro

				Livro livro = new Livro();
				livro.setIsbn(result.getString("isbn"));
				livro.setTitlo(result.getString("titulo"));
				livro.setEditora(result.getString("editora"));

				// inserindo contato na lista
				todosOsLivros.add(livro);
			}
			result.close();
			pst.close();
			return todosOsLivros;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return todosOsLivros;
	}

	public List<Livro> listarLivroPorTitulo(String titulo) {
		String consulta = "select * from livro where titulo like '%" + titulo
				+ "%'";
		PreparedStatement pst;
		List<Livro> todosOsLivros = new ArrayList<Livro>();

		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet result = pst.executeQuery();
			while (result.next()) {
				// cria o objeto Livro

				Livro livro = new Livro();
				livro.setIsbn(result.getString("isbn"));
				livro.setTitlo(result.getString("titulo"));
				livro.setEditora(result.getString("editora"));

				// inserindo contato na lista
				todosOsLivros.add(livro);
			}
			result.close();
			pst.close();
			return todosOsLivros;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(todosOsLivros.size());
		return todosOsLivros;
	}

	public Livro buscarLivro(Livro livro, int codigo) {
		String consulta = "select * from livro where titulo='"
				+ livro.getTitulo() + "'";
		PreparedStatement pst;
		boolean existe = false;
		Livro livroAux = new Livro();
		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet resultSet = pst.executeQuery();
			while (resultSet.next()) {

				livroAux.setTitlo(resultSet.getString("titulo"));
				livroAux.setCodigo(resultSet.getInt("id"));

			}
			resultSet.close();
			pst.close();
			return livroAux;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return livroAux;
	}
	//ranking dos livros mais comentados
	public List<Comentario> rankginComentario(){
		List<Comentario> comentarios = new ArrayList<Comentario>();
		String consulta ="select distinct titulo, count(codlivro) as soma from (livro join comentario on livro.id=codlivro) group by codlivro, titulo order by soma DESC";
		PreparedStatement pst;
		
		try {
			pst = this.conexao.prepareStatement(consulta);
			ResultSet result = pst.executeQuery();
			while (result.next()) {
				// cria o objeto Livro

				Comentario comentario = new Comentario();
				comentario.setTituloivro(result.getString("titulo"));
				comentario.setNumeroComentario(result.getInt("soma"));

				// inserindo contato na lista
				comentarios.add(comentario);
			}
			result.close();
			pst.close();
			return comentarios;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return comentarios;
	}

}